﻿using System;
using System.Data;
using System.Linq;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.IO;
using System.Reflection;

namespace Intel_Client_GUI
{
	public class PluginManager
	{
		public PluginManager()
		{
            Pp = new PluginProxy(this);
            Scan();
        }




        public void Scan()  //扫描插件
        {
			DirectoryInfo dir = new DirectoryInfo("GuiAddons");

            if (!dir.Exists)
            {
                dir.Create();
                return;
            }

            foreach (var File in dir.GetFiles("*.dll"))
            {
                try
                {
                    //Assembly plugin = Assembly.LoadFile(File.FullName);
                    //if (plugin != null)
                    //{
                    //    foreach (Type t in plugin.GetTypes())
                    //    {
                    //        if (t.GetInterfaces().Contains(typeof(IPlugin)))
                    //        {
                    //            IPlugin pg = (IPlugin)Activator.CreateInstance(t);
                    //            this.AddPlugin(pg);
                    //        }
                    //    }
                    //}
                    this.LoadPlugin(File.FullName);
                }
                catch (System.Exception ex)
                {
                    System.Windows.MessageBox.Show(ex.Message);
                }
               
            }
        }

        public void RegTimeCall(IPlugin plugin, PluginProxy.TimeScaleSetterCallBack cb) //注册TIMESCALE 回调函数
        {
            this.TimeCallBackDic.Add(plugin.Uuid, cb);
        }

        public void ChangeTimeScale(int Uuid, DateTime start, TimeSpan durtaion)        //对指定插件改变 TIME SCALE
        {
            if (!this.TimeCallBackDic.ContainsKey(Uuid))
                return;
			try
			{
           		this.TimeCallBackDic[Uuid](start, durtaion);
			}
			catch
			{}
        }

		public Page GetPage(int Uuid)				//获取指定页面
		{
            try
            {
                Page page = null;
                if (PageCache.ContainsKey(Uuid))				//优先检索Cache
                    page = PageCache[Uuid];
                else if (Plugins.ContainsKey(Uuid))			//检索插件
                {
                    page = Plugins[Uuid].GetPage(Pp);
                    PageCache.Add(Uuid, page);
                    //this.ChangeTimeScale(Uuid,Globle.DateTimeData);
                }
				if(this.TimeCallBackDic.ContainsKey(Uuid))
				{
					TimeCallBackDic[Uuid].Invoke(Globle.DateTimeData.TimeAndDuration.start,Globle.DateTimeData.TimeAndDuration.duration);
				}
                ActivePage = page;
                return (Page)page;
            }
            catch
            {
                return null;
            }			
		}

        public void AddPlugin(IPlugin pg)                           //添加插件
        {
            this.Plugins.Add(pg.Uuid, pg);
			if(this.OnPluginSetChanged!=null)
            	OnPluginSetChanged(pg.Uuid, pg.Name, PluginState.Add);
        }

        public void LoadPlugin(string Path)         //可能throw 错误
        {
            Assembly plugin = Assembly.LoadFile(Path);
            if (plugin != null)
            {
                foreach (Type t in plugin.GetTypes())
                {
                    if (t.GetInterfaces().Contains(typeof(IPlugin)))
                    {
                        IPlugin pg = (IPlugin)Activator.CreateInstance(t);
                        this.AddPlugin(pg);
                        //System.Windows.MessageBox.Show(pg.Uuid.ToString());
                    }
                }
            }
        }

        public void DeletePlugin(int Uuid)                          //删除插件
        {
            if (!Plugins.ContainsKey(Uuid))
            {
                return;
            }
            else
            {
                var p = Plugins[Uuid];
				if(this.OnPluginSetChanged!=null)
               		OnPluginSetChanged(p.Uuid,p.Name,PluginState.Delete);
                Plugins.Remove(Uuid);
            }
            
        }

        public bool Contains(int Uuid)
        {
            return this.Plugins.ContainsKey(Uuid);
        }


        public Dictionary<int, string> PluginsSet
        {
            get
            {
                Dictionary<int, string> _ps = new Dictionary<int, string>();
                foreach (var P in Plugins.Values)
                {
                    _ps.Add(P.Uuid, P.Name);
                }
				//System.Windows.MessageBox.Show(_ps.Count.ToString());
                return _ps;
            }
        }

        public Page ActivePage { get; private set; }





		public delegate void PluginChangeHandler(int Uuid,string Name,PluginState s);

        public event PluginChangeHandler OnPluginSetChanged;





        private Dictionary<int, IPlugin> Plugins = new Dictionary<int, IPlugin>();

        private Dictionary<int, Page> PageCache = new Dictionary<int, Page>();

        private Dictionary<int, PluginProxy.TimeScaleSetterCallBack> TimeCallBackDic = new Dictionary<int, PluginProxy.TimeScaleSetterCallBack>();

        private PluginProxy Pp;




        public enum PluginState { Add, Delete }
	}
}